﻿using System;
using System.Collections.Generic;
using System.Text;

using YouHP.Model;
using YouHP.DALFactory;
using YouHP.Utility;
using YouHP.BLL.MedicalGraph;
using System.IO;

namespace YouHP.BLL
{
    public class PatientBLL
    {

        #region 单件模式
        static PatientBLL _Instance;

        public static PatientBLL Instance
        {
            get
            {
                if (_Instance == null)
                {
                    _Instance = new PatientBLL();
                }
                return _Instance;
            }
        }
        #endregion

        #region 疾病记录
        public PatientRecordInfo GetPatientRecordInfoById(int id)
        {
            return DataAccess.PatientDAL.GetPatientRecordById(id);
        }

#if GENDATA
        public PatientRecordInfo GetPatientRecordInfo(int userId)
        {
            PatientRecordInfo prData = new PatientRecordInfo();
            prData.StartDate = Convert.ToDateTime("2006-03-03");
            prData.RecordDate = Convert.ToDateTime("2007-04-04");
            prData.UpdateDate = Convert.ToDateTime("2008-05-20");
            prData.PatientId = userId;
            prData.PatientName = "测试帐户";
            prData.DiseaseId = 10;
            prData.DiseaseName = "感冒";
            prData.Id = 101;
            prData.ConfirmHospital = "上海市第一人民医院";
            return prData;
        }
#else
        public PatientRecordInfo GetPatientRecordInfo(int userId)
        {
            return DataAccess.PatientDAL.GetPatientRecordByUserId(userId);
        }
#endif

        public bool AddPatientRecord(PatientRecordInfo info)
        {
            return DataAccess.PatientDAL.AddDiseaseRecorde(info);
        }

        public bool UpdatePatientRecord(PatientRecordInfo info)
        {
            return DataAccess.PatientDAL.UpdateDiseaseRecorde(info);
        }
        #endregion

        #region 症状记录（废弃的）

        public bool AddSymptomRecordes(SymptomRecordesInfo info)
        {
            bool succ =  DataAccess.PatientDAL.AddSymptomRecordes(info);
            if (succ)
            {
                MakeGraphSymptom(info.PatientRecordId);
            }
            return succ;
        }

        public bool UpdateSymptomRecordes(SymptomRecordesInfo info)
        {
            bool succ =  DataAccess.PatientDAL.UpdateSymptomRecordes(info);
            if (succ)
            {
                MakeGraphSymptom(info.PatientRecordId);
            }
            return succ;
        }

        // 根据日期段获取填写的症状记录信息列表
        public List<SymptomRecordesInfo> GetSymptomRecordesList(int prId, DateTime startDate, DateTime EndDate)
        {
            return new List<SymptomRecordesInfo>(1);
        }

        public List<SymptomRecordesInfo> GetSymptomRecordesList(int prid)
        {
            return DataAccess.PatientDAL.GetSymptomRecordesList(1000, 1, prid, DateTime.Now);
        }

        public bool DelSymptomRecordes(int prid, int[] itemIds)
        {
            bool succ = DataAccess.PatientDAL.DelSymptomRecordes(prid,itemIds);
            if (succ)
            {
                MakeGraphSymptom(prid);
            }
            return succ;
        }

        public SymptomRecordesInfo GetSymptomRecordes(int id, int prid)
        {
            return DataAccess.PatientDAL.GetSymptomRecordes(id, prid);
        }

        /// 根据记录的日期获取填写的症状记录信息
        public SymptomRecordesInfo GetSymptomRecordes(int prid, DateTime recodeDate)
        {
            return new SymptomRecordesInfo();
        }

        #endregion  

        #region 实验室指标（废弃的）

        public bool AddLabcheckRecordes(LabcheckRecordesInfo info)
        {
            return DataAccess.PatientDAL.AddLabcheckRecordes(info);
        }

        public bool DelLabcheckesRecordes(int[] idItems, int prid)
        {
            return DataAccess.PatientDAL.DelLabcheckRecordes(idItems, prid);
        }

        public bool UpdateLabcheckRecordes(LabcheckRecordesInfo info)
        {
            return DataAccess.PatientDAL.UpdateLabcheckRecordes(info);
        }

        public LabcheckRecordesInfo GetLabcheckRecordes(int id, int prid)
        {
            return DataAccess.PatientDAL.GetLabcheckRecordes(id, prid);
        }

        /// <summary>
        /// 根据记录的日期获取填写的实验室记录信息
        /// </summary>
        /// <param name="prid">病人疾病记录id</param>
        /// <param name="recodeDate">填写记录的日期</param>
        /// <returns></returns>
        public LabcheckRecordesInfo GetLabCheckRecordes(int prid, DateTime recodeDate)
        {
            return new LabcheckRecordesInfo();
        }

        public List<LabcheckRecordesInfo> GetLabcheckRecordesList(int prid)
        {
            int pageSize = 3000;
            int pageIndex = 1;
            int count = 0;
            return DataAccess.PatientDAL.GetLabcheckRecordesList(pageSize, pageIndex, prid, out count);
        }

        #endregion

        #region 一般情况（体重）


#if GENDATA
        public WeightHistoryInfo GetCurrentWeight(int prId)
        {
            WeightHistoryInfo info = new WeightHistoryInfo();
            info.Id = 100;
            info.HeightUnits = "米";
            info.MeasurementUnits = "千克";
            info.Height = 1.65;
            info.RecordDate = Convert.ToDateTime("2008-05-01");
            info.DataValue = 67.5;
            return info;
        }
#else
        public WeightHistoryInfo GetCurrentWeight(int prId)
        {
            return DataAccess.PatientWeightDAL.GetCurrentWeight(prId);
        }
#endif

        /// <summary>
        /// 取得病人所有的体重记录历史（根据察看模式）
        /// </summary>
        public List<WeightHistoryInfo> GetWeightHistoryList(int prId, int viewMode)
        {
            DateTime minDate = new DateTime(1900, 1, 1);
            List<WeightHistoryInfo> weightLst = null;
            switch (viewMode)
            {
                case Constants.WEEKMODE:
                    break;
                case Constants.MONTHMODE:
                    break;
                case Constants.THREEMONTHMODE:
                    break;
                case Constants.YEARMODE:
                    break;
                case Constants.ALLMODE:
                default:
                    weightLst = DataAccess.PatientWeightDAL.GetWeightHistoryList(prId, minDate, DateTime.Now);
                    break;
            }

            return weightLst;
        }

        public List<WeightHistoryInfo> GetWeightHistoryList(int prId)
        {
            return DataAccess.PatientWeightDAL.GetWeightHistoryList(prId);
        }

        public List<WeightHistoryInfo> GetWeightHistoryList(int prId, int PageSize, int page, out int DataCount)
        {
            return DataAccess.PatientWeightDAL.GetWeightHistoryList(prId, PageSize, page, out DataCount);
        }

        public bool UpdateWeightHistory(WeightHistoryInfo whInfo)
        {
            return DataAccess.PatientWeightDAL.UpdateWeightHistory(whInfo);
        }

        public bool AddWeightHistory(WeightHistoryInfo whInfo)
        {
            return DataAccess.PatientWeightDAL.AddWeightHistory(whInfo);
        }

        public bool DeleteWeightHistory(int prId, int whid)
        {
            return DataAccess.PatientWeightDAL.DeleteWeightHistory(prId, whid);
        }

        public WeightHistoryInfo GetWeightHistory(int prId, int whId)
        {
            return DataAccess.PatientWeightDAL.GetWeightHistory(prId, whId);
        }

        //判断历史记录表中是否已存在病人指定时间对应的记录
        public bool CheckWeightHistory(int prId, DateTime recordDate)
        {
            return DataAccess.PatientWeightDAL.CheckWeightHistory(prId, recordDate);
        }

        #endregion

        #region 病人身高

#if GENDATA
        public bool UpdatePatientHeight(int patientId, double height)
        {
            return true;
        }
#else
        public bool UpdatePatientHeight(int patientId, double height)
        {
            return DataAccess.PatientWeightDAL.UpdatePatientHeight(patientId, height);
        }
#endif

#if GENDATA
        public double GetPatientHeight(int patientId)
        {
            return 1.78;
        }
#else
        public double GetPatientHeight(int patientId)
        {
            return DataAccess.PatientWeightDAL.GetPatientHeight(patientId);
        }
#endif
        #endregion

        #region 绘图

        public bool MakeGraphGeneral(int prid,int diseaseId)
        {
            return true;
        }

        public bool MakeGraphLabcheck(int prid)
        {
            PatientRecordInfo prinfo = PatientBLL.Instance.GetPatientRecordInfoById(prid);
            if (prinfo.Id <= 0) return false;
            DiseaseGraphSettingInfo settinginfo = DiseaseBLL.Instance.GetDiseaseGraphSettingInfo(prinfo.DiseaseId);
            GraphSetting setting = SerializationHelper.DeserializeFromXml<GraphSetting>(settinginfo.GraphLabcheckSetting);
            foreach (GraphRule rule in setting.ParamList)
            {
                foreach (GraphRule.Group group in rule.mGroups)
                {
                    foreach (GraphRule.Variable var in group.mVariables)
                    {
                        try
                        {
                            int id = Convert.ToInt32(var.mKey);
                            LabcheckInfo labcheck = LabcheckBLL.Instance.GetLabcheckInfo(Convert.ToInt32(var.mKey));
                            var.mName = labcheck.Name;
                            var.ShortName = labcheck.ShortName;
                            string[] spliter = new string[] { "@", ",", " ", "　" };
                            string[] normalValues = labcheck.NormalValues.Split(spliter,StringSplitOptions.RemoveEmptyEntries);
                            double minValue = Convert.ToDouble(normalValues[0]);
                            double maxValue = Convert.ToDouble(normalValues[1]);
                            var.SetRange0(minValue,maxValue);
                            string[] gridValue = labcheck.GridValues.Split(spliter, StringSplitOptions.RemoveEmptyEntries);
                            var.GridValue.Clear();
                            foreach (string str in gridValue)
                            {
                                var.GridValue.Add(Convert.ToDouble(str));
                            }
                            var.Unit = string.Format("(单位：{0})",labcheck.MeasurementUnits);
                        }
                        catch 
                        {
                            continue;
                        }
                        
                    }
                }
            }

            List<LabcheckRecordesInfo> lst = this.GetLabcheckRecordesList(prid);
            DataSpliter dataSpliter = new DataSpliter();
            GraphDataManager data = new GraphDataManager();
            DateTime dt1;
            DateTime dt2 = DateTime.Now;
            foreach (LabcheckRecordesInfo record in lst)
            {
                dt1 = record.RecordDate;
                dataSpliter.SetDataString(record.LabcheckInfo);
                foreach (KeyValuePair<string, string> item in dataSpliter.DataDictionary)
                {
                    GraphDataItemInfo dataItem = new GraphDataItemInfo();
                    dataItem.Value = item.Value;
                    data.AddData(item.Key, dt1, dt2, item.Value);
                }
            }

            GraphLabcheck graph = new GraphLabcheck();
            string spath = Utils.GetMapPath("~/userdata/" + prid);
            graph.SetPath(spath);
            graph.SetWebPath("/userdata/" + prid);
            graph.Setting = setting;
            graph.Data = data;
            graph.MakeGraph();
            GraphResult result = graph.Result;
            prinfo.Id = prid;
            //prinfo.GraphLabcheckPath = result.GraphWebPath;
            DataAccess.PatientDAL.UpdatePatientRecord_GraphLabcheckPath(prinfo);
            return true;   
        }

        public bool MakeGraphSymptom(int prid)
        {
            PatientRecordInfo prinfo = PatientBLL.Instance.GetPatientRecordInfoById(prid);
            if (prinfo.Id <= 0) return false;
            
            GraphSetting setting = new GraphSetting();
            GraphRule rule = new GraphRule();
            setting.ParamList.Add(rule);

            GraphRule.Group group = new GraphRule.Group();
            rule.AddGroup(group);
            group.mName = "主要症状";
            List<DiseaseSymptomInfo> symptomLst =
                DiseaseBLL.Instance.GetDiseaseSymptomList(prinfo.DiseaseId, Constants.PRIMARY_SYMPTOM);
            foreach (DiseaseSymptomInfo info in symptomLst)
            {
                GraphRule.Variable var = new GraphRule.Variable();
                var.mKey = info.SymptomId.ToString();
                var.mName = info.SymptomName;
                group.AddVariable(var);
            }

            group = new GraphRule.Group();
            rule.AddGroup(group);
            group.mName = "次要症状";
            symptomLst = DiseaseBLL.Instance.GetDiseaseSymptomList(prinfo.DiseaseId, Constants.SECOND_SYMPTOM);
            foreach (DiseaseSymptomInfo info in symptomLst)
            {
                GraphRule.Variable var = new GraphRule.Variable();
                var.mKey = info.SymptomId.ToString();
                var.mName = info.SymptomName;
                group.AddVariable(var);
            }


            List<SymptomRecordesInfo> lst = this.GetSymptomRecordesList(prid);
            DataSpliter dataSpliter = new DataSpliter();
            GraphDataManager data = new GraphDataManager();
            DateTime dt1;
            DateTime dt2 = DateTime.Now;
            foreach (SymptomRecordesInfo record in lst)
            {
                dt1 = record.RecordDate;
                dataSpliter.SetDataString(record.SymptomInfo);
                foreach (KeyValuePair<string, string> item in dataSpliter.DataDictionary)
                {
                    GraphDataItemInfo dataItem = new GraphDataItemInfo();
                    dataItem.Value = item.Value;
                    data.AddData(item.Key, dt1, dt2, item.Value);
                }
            }

            GraphSymptom graph = new GraphSymptom();
            string spath = Utils.GetMapPath("~/userdata/" + prid);
            graph.SetPath(spath);
            graph.SetWebPath("/userdata/" + prid);
            graph.Setting = setting;
            graph.Data = data;
            graph.MakeGraph();
            GraphResult result = graph.Result;
            prinfo.Id = prid;
            prinfo.GraphSymptomPath = result.GraphWebPath;
            DataAccess.PatientDAL.UpdatePatientRecord_GraphSymptomPath(prinfo);
            return true;
        }

        public bool MakeGraphTreatment(int prid)
        {
            PatientRecordInfo prinfo = GetPatientRecordInfoById(prid);
            List<DiseaseTreatmentInfo> treatmentLst = DiseaseBLL.Instance.GetDiseaseTreatmentList(prinfo.DiseaseId);
            GraphSetting setting = new GraphSetting();
            GraphRule rule = new GraphRule();
            setting.ParamList.Add(rule);
            GraphRule.Group group = new GraphRule.Group();
            group.mName = "医生建议";
            rule.mGroups.Add(group);

            foreach (DiseaseTreatmentInfo info in treatmentLst)
            {
                GraphRule.Variable var = new GraphRule.Variable();
                var.mKey = info.TreatmentId.ToString();
                var.mName = info.TreatmentName;
                group.AddVariable(var);
            }

            List<TreatmentHistoryInfo> treatLst = PatientTreatmentBLL.Instance.GetAllCurUsedTreatments(prid);
            MedicalGraph.GraphDataManager data = new GraphDataManager();
            foreach (TreatmentHistoryInfo info in treatLst)
            {
                List<TreatmentHistoryInfo> historyList = PatientTreatmentBLL.Instance.GetAllUseHistoryTreatments(prid, info.TreatmentId);
                foreach (TreatmentHistoryInfo item in historyList)
                {
                    string key = item.TreatmentId.ToString();
                    string dosage = item.DataValue + item.Unit;
                    DateTime enddate = DateTime.Now;
                    if (item.State != 0) enddate = item.EndDate;
                    string purpose = item.UsePurpose.ToString();
                    data.AddData(key, item.StartDate, enddate, purpose, dosage);
                }
            }

            GraphTreatment graph = new GraphTreatment();
            string spath = Utils.GetMapPath("~/userdata/" + prid);
            graph.SetPath(spath);
            graph.SetWebPath("/userdata/" + prid);
            graph.Setting = setting;
            graph.Data = data;
            graph.MakeGraph();
            GraphResult result = graph.Result;
            prinfo.Id = prid;
            prinfo.GraphTreatmentPath = result.GraphWebPath;
            DataAccess.PatientDAL.UpdatePatientRecord_GraphTreatmentPath(prinfo);

            return true;
        }

        public void MakeFlashGraphGeneral(PatientRecordInfo PrData)
        {
            PatientRecordInfo info = PrData;

            StringBuilder sb = new StringBuilder();
            sb.Append("&General=1&\r\n");
            sb.AppendFormat("&StartDate={0:yyyy-MM-dd}&\r\n", info.StartDate);
            sb.AppendFormat("&DosageDate={0:yyyy-MM-dd}&\r\n", info.ConfirmDate);
            sb.AppendFormat("&UpdateDate={0:yyyy-MM-dd}&\r\n", info.UpdateDate);
            List<WeightHistoryInfo> lst = this.GetWeightHistoryList(info.Id);
            string str1 = "&Time1=";
            string str2 = "&Value1=";
            string str3 = "&Time2=";
            string str4 = "&Value2=";
            int i = 0;
            foreach (WeightHistoryInfo item in lst)
            {
                if (i > 0)
                {
                    str1 += ";";
                    str2 += ";";
                    str3 += ";";
                    str4 += ";";
                }
                str1 += item.RecordDate.ToString("yyyy-MM-dd");
                str2 += item.DataValue.ToString();
                str3 += item.RecordDate.ToString("yyyy-MM-dd");
                str4 += (item.DataValue / item.Height / item.Height).ToString();
            }
            str1 += "&\r\n";
            str2 += "&\r\n";
            str3 += "&\r\n";
            str4 += "&\r\n";
            sb.Append(str1);
            sb.Append(str2);
            sb.Append(str3);
            sb.Append(str4);


            string path = string.Format("~/datafiles/patient/{0}/", info.Id);
            Utils.WriteTextFile(path, "general.txt", sb.ToString());
            path = string.Format("/datafiles/patient/{0}/general.txt", info.Id);
            PrData.GraphSymptomPath = path;
            //PrData.GraphGeneralHeight = 320;
        }

        public void MakeFlashGraphSymptom(PatientRecordInfo prData)
        {
           

            StringBuilder sb = new StringBuilder();
            sb.Append("&General=1&\r\n");
            sb.AppendFormat("&StartDate={0:yyyy-MM-dd}&\r\n", prData.StartDate);
            sb.AppendFormat("&DosageDate={0:yyyy-MM-dd}&\r\n", prData.ConfirmDate);
            sb.AppendFormat("&UpdateDate={0:yyyy-MM-dd}&\r\n", prData.UpdateDate);

            
            sb.Append("&GroupCount=2&\r\n");
            List<DiseaseSymptomInfo> symptomLst;

            symptomLst = DiseaseBLL.Instance.GetDiseaseSymptomList(prData.DiseaseId, Constants.PRIMARY_SYMPTOM);
            sb.AppendFormat("&Group1=主要症状;{0}&\r\n",symptomLst.Count);
            int i = 0;
            int count = 0;
            
            foreach (DiseaseSymptomInfo item in symptomLst)
            {
                i++;
                sb.AppendFormat("&Var_1_{0}={0}&\r\n", item.SymptomName);
                string str1 = string.Format("&Time_1_{0}=",i);
                string str2 = string.Format("&Value_1_{0}=",i);
                List<SymptomHistoryInfo> lst = PatientSymptomBLL.Instance.GetSymptomHistoryList(prData.Id, item.SymptomId, 100000, 1, out count);
                int j = 0;
                foreach (SymptomHistoryInfo info in lst)
                {
                    if (j > 0)
                    {
                        str1 += ";";
                        str2 += ";";
                    }
                    str1 += info.RecordDate.ToString("yyyy-MM-dd");
                    str2 += info.DegreeValue.ToString();
                    j++;
                }
                str1 += "&\r\n";
                str2 += "&\r\n";
                sb.Append(str1);
                sb.Append(str2);
            }
            int symcnt = symptomLst.Count ;
            if (symcnt < 4) symcnt = 4;
            symcnt += 1;

            symptomLst = DiseaseBLL.Instance.GetDiseaseSymptomList(prData.DiseaseId, Constants.SECOND_SYMPTOM);
            sb.AppendFormat("&Group2=次要症状;{0}&\r\n",symptomLst.Count);
            i = 0;
            foreach (DiseaseSymptomInfo item in symptomLst)
            {
                i++;
                sb.AppendFormat("&Var_2_{0}={0}&\r\n", item.SymptomName);
                string str1 = string.Format("&Time_2_{0}=", i);
                string str2 = string.Format("&Value_2_{0}=", i);
                List<SymptomHistoryInfo> lst = PatientSymptomBLL.Instance.GetSymptomHistoryList(prData.Id, item.SymptomId, 100000, 1, out count);
                int j = 0;
                foreach (SymptomHistoryInfo info in lst)
                {
                    if (j > 0)
                    {
                        str1 += ";";
                        str2 += ";";
                    }
                    str1 += info.RecordDate.ToString("yyyy-MM-dd");
                    str2 += info.DegreeValue.ToString();
                    j++;
                }
                str1 += "&\r\n";
                str2 += "&\r\n";
                sb.Append(str1);
                sb.Append(str2);
            }
            symcnt += 1;
            symcnt += symptomLst.Count;

            string path = string.Format("~/datafiles/patient/{0}/", prData.Id);
            Utils.WriteTextFile(path, "symptom.txt", sb.ToString());
            path = string.Format("/datafiles/patient/{0}/symptom.txt", prData.Id);
            prData.GraphSymptomPath = path;
            //prData.GraphSymptomHeight = symcnt * 30 + 80;

        }

        public void MakeFlashGraphTreatment(PatientRecordInfo prData)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("&Treatment=1&\r\n");
            sb.AppendFormat("&StartDate={0:yyyy-MM-dd}&\r\n", prData.StartDate);
            sb.AppendFormat("&DosageDate={0:yyyy-MM-dd}&\r\n", prData.ConfirmDate);
            sb.AppendFormat("&UpdateDate={0:yyyy-MM-dd}&\r\n", prData.UpdateDate);

            sb.Append("&GroupCount=1&\r\n");
            List<DiseaseTreatmentInfo> treatmentLst = DiseaseBLL.Instance.GetDiseaseTreatmentList(prData.DiseaseId);
            sb.AppendFormat("&Group1=医生建议;{0}&\r\n",treatmentLst.Count);
            int gidx = 1;
            int varidx = 1;
            int trcount = 1;
            foreach (DiseaseTreatmentInfo info in treatmentLst)
            {
                trcount++;
                int count = 0;
                int valueidx = 1;
                List<TreatmentHistoryInfo> historyList = PatientTreatmentBLL.Instance.GetTreatmentHistoryList(prData.Id, info.TreatmentId, 100000, 1, out count);
                sb.AppendFormat("&Var_{0}_{1}={2};{3}&\r\n", gidx, varidx,info.TreatmentName,historyList.Count);
                foreach (TreatmentHistoryInfo item in historyList)
                {
                    sb.AppendFormat("&Value_{0}_{1}_{2}={3};{4};{5};{6};&\r\n",
                        gidx, varidx, valueidx,
                        item.StartDate.ToString("yyyy-MM-dd"),
                        item.EndDate.ToString("yyyy-MM-dd"),
                        item.UsePurpose,
                        item.DataValue,
                        item.Unit);
                    valueidx++;
                }
                varidx++;
            }
            string path = string.Format("~/datafiles/patient/{0}/", prData.Id);
            Utils.WriteTextFile(path, "treatment.txt", sb.ToString());
            path = string.Format("/datafiles/patient/{0}/treatment.txt", prData.Id);
            prData.GraphTreatmentPath = path;
            //prData.GraphTreatmentHeight = trcount * 30 + 80;
        }

        #endregion

        #region 病人检索

#if GENDATA

        public List<UserInfo> GetPatientList(int pageSize, int pageIndex, PatientSearchCondition psCond, out int count)
        {
            count = 100;
            List<UserInfo>  lst = new List<UserInfo>();
            for (int i = 1; i < 10; i++)
            {
                UserInfo info = new UserInfo();
                info.Id = 100 * i + i;
                info.UserName = "病人";
                info.Intro = "病人简介病人简介病人简介病人简介病人简介病人简介病人简介";
                info.Avatar = "/support/dnt/avatars/common/1.jpg";
                info.Age = 20;
                info.Gender = "男";
                info.DiseaseId = 10;
                info.DiseaseName = "糖尿病";
                lst.Add(info);
            }
            return lst;
        }

#else
        /// <summary>
        /// 根据组合条件来获取病人列表
        /// </summary>
        public List<UserInfo> GetPatientList(int pageSize, int pageIndex, PatientSearchCondition psCond, out int count)
        {
            if (psCond.DiseaseId > 0 && psCond.SymptomId > 0 || psCond.DiseaseId > 0 && psCond.TreatmentId > 0 ||
                psCond.SymptomId > 0 && psCond.TreatmentId > 0)
            {
                psCond.IsAdvanceSearch = 1;     //如果组合了疾病和症状，则强制修改为高级搜索条件
            }
            else
            {
                psCond.IsAdvanceSearch = 0;
            }

            if (psCond.IsAdvanceSearch > 0) //高级检索
            {
                return DataAccess.PatientDAL.GetPatientListByAdvanceSearch(pageSize, pageIndex, psCond.ToSqlConditonString(), 
                    psCond.ToOrderByString() , psCond.IsQueryCurrent, out count);
            }
            else if(psCond.PatientName.Length > 0 || psCond.ProvinceId > 0 || psCond.CityId > 0 
                || psCond.AgeStart > 0 || psCond.AgeEnd > 0)    //内部条件
            {
                List<UserInfo> tempUserList =  DataAccess.PatientDAL.GetPatientList(
                    pageSize, 
                    pageIndex, 
                    psCond.ToSqlConditonString(),
                    psCond.ToOrderByString(), 
                    out count);
                if (tempUserList.Count == 0)
                {
                    // Resort to GetAllPatientList
                    tempUserList = DataAccess.PatientDAL.GetAllPatientsList(
                        pageSize,
                        pageIndex,
                        psCond.ToSqlConditonString(),
                        psCond.ToOrderByString(),
                        out count);
                }

                return tempUserList;
            }
            else if(psCond.DiseaseId > 0 )  //联合疾病信息
            {
                return DataAccess.PatientDAL.GetPatientListByDisease(pageSize, pageIndex, psCond.ToSqlConditonString(),
                    psCond.ToOrderByString(), out count);
            }
            else if (psCond.SymptomId > 0)  //联合症状信息
            {
                return DataAccess.PatientDAL.GetPatientListBySymptom(pageSize, pageIndex, psCond.ToSqlConditonString(),
                    psCond.ToOrderByString(), psCond.IsQueryCurrent, out count);
            }
            else if (psCond.TreatmentId > 0 || psCond.TreatmentName != "")    //联合治疗信息
            {
                return DataAccess.PatientDAL.GetPatientListByTreatment(pageSize, pageIndex, psCond.ToSqlConditonString(),
                    psCond.ToOrderByString(), psCond.IsQueryCurrent, out count);
            }

            //return DataAccess.PatientDAL.GetPatientList(pageSize, pageIndex, "",
            //        psCond.ToOrderByString(), out count);
            return DataAccess.PatientDAL.GetAllPatientsList(pageSize, pageIndex, "",
                        psCond.ToOrderByString(), out count);
        }

        /// <summary>
        /// 取得Top n 个有此症状的疾病,以及疾病对应的典型病人(按照疾病对应的病人数来降序排列)
        /// </summary>
        public List<UserInfo> GetHottestPatientBySymptomId(int sympId, int n)
        {
            string conStr = string.Format("SymptomId={0}", sympId);
            string order = "ViewCount desc";
            int count = 0;
            int isQueryCurrent = 1;
            return DataAccess.PatientDAL.GetPatientListBySymptom(n,1,conStr,order, isQueryCurrent, out count);
        }

#endif
        /// <summary>
        /// 获取最新加入的n个病人
        /// </summary>
        public List<UserInfo> GetLastestPatient(int n)
        {
            int count = 0 ;
            PatientSearchCondition psCond = new PatientSearchCondition();
            psCond.OrderByField = PatientSearchCondition.REGISTERED_DATE;

            return DataAccess.PatientDAL.GetLatestPatientList(n, 1, psCond.ToSqlConditonString(),
                psCond.ToOrderByString(), out count);
        }

        /// <summary>
        /// 获得最新加入的，并且患某种疾病的n个病人，如果diseaseId小于等于0，此函数同GetLastestPatient
        /// </summary>
        public List<UserInfo> GetLatestPatientByDisease(int n, int diseaseId)
        {
            if (diseaseId <= 0)
                return GetLastestPatient(n);

            int count = 0;
            PatientSearchCondition psCond = new PatientSearchCondition();
            psCond.OrderByField = PatientSearchCondition.REGISTERED_DATE;
            psCond.DiseaseId = diseaseId;

            return DataAccess.PatientDAL.GetPatientListByDisease(n, 1, psCond.ToSqlConditonString(),
                psCond.ToOrderByString(), out count);
        }

        /// <summary>
        /// 获取最活跃的N各成员 （added by sam)
        /// </summary>
        public List<UserInfo> GetPatientDataListActive(int n)
        {
            int count = 0;
            PatientSearchCondition psCond = new PatientSearchCondition();
            psCond.OrderByField = PatientSearchCondition.UPDATE_TIME;

            return DataAccess.PatientDAL.GetPatientList(n, 1, psCond.ToSqlConditonString(),
                psCond.ToOrderByString(), out count);
        }

        /// <summary>
        /// 获取最活跃的的，并且患有某种疾病的n个成员，
        /// 如果diseaseId小于等于0，则此函数同GetPatientDataListActive
        /// </summary>
        public List<UserInfo> GetPatientDataListActiveByDisease(int n, int diseaseId)
        {
            if (diseaseId <= 0)
                return GetPatientDataListActive(n);

            int count = 0;
            PatientSearchCondition psCond = new PatientSearchCondition();
            psCond.OrderByField = PatientSearchCondition.UPDATE_TIME;
            psCond.DiseaseId = diseaseId;

            return DataAccess.PatientDAL.GetPatientListByDisease(n, 1, psCond.ToSqlConditonString(),
                psCond.ToOrderByString(), out count);
        }

        /// <summary>
        /// 取得Top n 个感染此疾病病人(按关注次数排序)(added by Sam)
        /// </summary>
        public List<UserInfo> GetHottestPatientByDisease(int diseaseId, int n)
        {
            string conStr = string.Format("DiseaseId={0}", diseaseId);
            int count = 0;
            return DataAccess.PatientDAL.GetPatientListByDisease(n, 1, conStr, "[ViewCount] desc", out count);
            
        }

#if GENDATA
        /// <summary>
        /// 取得Top n 个正在使用此治疗方案的病人(按关注次数排序)
        /// </summary>
        public List<UserInfo> GetHottestPatientByTreatment(int treatmentId, int n)
        {
            List<UserInfo>  lst = new List<UserInfo>();
            for (int i = 0; i < n; i++)
            {
                UserInfo info = new UserInfo();
                info.Id = i;
                info.Avatar = "/support/dnt/avatars/common/1.jpg";
                info.UserName = "用户名";
                lst.Add(info);
            }
            return lst;
        }
#else
        public List<UserInfo> GetHottestPatientByTreatment(int treatmentId, int n)
        {
            string conStr = string.Format("treatmentid={0}", treatmentId);
            int count = 0;
            int isQueryCurrent = 1;
            return DataAccess.PatientDAL.GetPatientListByTreatment(n, 1, conStr, "[ViewCount] desc", isQueryCurrent, out count);
        }
#endif

        // 已知bestFitPrIds对于的病友的症状数目一致，根据症状的严重程度筛选最相似的
        private List<int> GetBestFitPatientRecordIdsBySymptomSeverity(List<int> bestFitPrIds,
            Dictionary<int, int> PrIdAndSymptomSeverityViolationCountDict)
        {
            int minimumViolationCount = 10000;

            foreach (KeyValuePair<int, int> pair in PrIdAndSymptomSeverityViolationCountDict)
            {
                if (pair.Value < minimumViolationCount && bestFitPrIds.Contains(pair.Key))
                {
                    minimumViolationCount = pair.Value;
                }
            }

            List<int> returnBestFitPrIds = new List<int>();

            // 已经找到了最小的症状严重程度的违规数
            foreach (KeyValuePair<int, int> pair in PrIdAndSymptomSeverityViolationCountDict)
            {
                if (pair.Value == minimumViolationCount && bestFitPrIds.Contains(pair.Key))
                {
                    returnBestFitPrIds.Add(pair.Key);
                }
            }

            return returnBestFitPrIds;
        }

        // 其他病友拥有当前病友所有的症状，选择其他病友中症状数与当前病友最接近的，
        // 如果有N个这样的其他病友，再根据症状的严重程度筛选
        private List<int> GetBestFitPatientRecordIdsBySymptomsCount(List<int> bestFitPrIds,
            Dictionary<int, int> PrIdAndSymptomsCount,
            Dictionary<int, int> PrIdAndSymptomSeverityViolationCountDict)
        {
            int minimumSymptomCount = 10000;

            foreach (KeyValuePair<int, int> pair in PrIdAndSymptomsCount)
            {
                if (bestFitPrIds.Contains(pair.Key) && pair.Value < minimumSymptomCount)
                {
                    minimumSymptomCount = pair.Value;
                }
            }

            List<int> returnBestFitPrIds = new List<int>();

            foreach (KeyValuePair<int, int> pair in PrIdAndSymptomsCount)
            {
                if (bestFitPrIds.Contains(pair.Key) && pair.Value == minimumSymptomCount)
                {
                    returnBestFitPrIds.Add(pair.Key);
                }
            }

            if (returnBestFitPrIds.Count > 1)
            {
                return GetBestFitPatientRecordIdsBySymptomSeverity(returnBestFitPrIds, PrIdAndSymptomSeverityViolationCountDict);
            }

            return returnBestFitPrIds;
        }

        // 获取和输入病人症状最接近的病人列表
        public List<UserInfo> GetBestFitSymptomsPatientList(int prId)
        {
            // 首先获得该病人的症状（所有症状，包括严重程度为0的症状）
            List<SymptomHistoryInfo> allSymptoms = PatientSymptomBLL.Instance.GetCurrentSymptomList(prId);
            
            // 不要浪费时间
            if (allSymptoms == null || allSymptoms.Count == 0)
                return null;

            // 找到严重程度为1,2,3的症状
            List<SymptomHistoryInfo> symptoms = new List<SymptomHistoryInfo>();
            foreach (SymptomHistoryInfo symptom in allSymptoms)
            {
                if (symptom.DegreeValue > Constants.SYMPTOM_NONE)
                {
                    symptoms.Add(symptom);
                }
            }

            // 如果没有严重程度为1,2,3的症状，比较严重程度为0的症状
            int symptomsCount = symptoms.Count;
            if (symptomsCount == 0)
            {
                return null;
            }


            #region 至此，说明病人有严重程度为1,2,3的症状

            Dictionary<int, int> PrIdAndSymptomsCount = new Dictionary<int, int>();
            Dictionary<int, int> PrIdAndFitSymptomsCountDict = new Dictionary<int, int>();
            Dictionary<int, int> PrIdAndSymptomSeverityViolationCountDict = new Dictionary<int, int>();

            int maximumFitSymptomCount = 0;
            int maximumSymptomSeverityViolationCount = 0;

            foreach (SymptomHistoryInfo symptom in symptoms)
            {
                int symptomId = symptom.SymptomId;

                List<SymptomHistoryInfo> records
                    = PatientSymptomBLL.Instance.GetCurrentSymptomListBySymptomAndDegreeValue(symptomId, -1);
                foreach (SymptomHistoryInfo record in records)
                {
                    if (record.PRId == prId)    // 自己
                        continue;

                    if (record.DegreeValue <= Constants.SYMPTOM_NONE)
                        continue;

                    if (PrIdAndFitSymptomsCountDict.ContainsKey(record.PRId))
                    {
                        PrIdAndFitSymptomsCountDict[record.PRId]++;
                    }
                    else
                    {
                        PrIdAndFitSymptomsCountDict.Add(record.PRId, 1);
                    }

                    if (PrIdAndFitSymptomsCountDict[record.PRId] > maximumFitSymptomCount)
                        maximumFitSymptomCount = PrIdAndFitSymptomsCountDict[record.PRId];

                    if (!PrIdAndSymptomsCount.ContainsKey(record.PRId))
                    {
                        List<SymptomHistoryInfo> localSymptoms = PatientSymptomBLL.Instance.GetCurrentSymptomList(record.PRId);
                        // 此处获得的症状包含严重程度为0的症状
                        int localSymptomsCount = 0;
                        foreach (SymptomHistoryInfo historyInfo in localSymptoms)
                        {
                            if (historyInfo.DegreeValue > Constants.SYMPTOM_NONE)
                                localSymptomsCount++;
                        }
                        PrIdAndSymptomsCount.Add(record.PRId, localSymptomsCount);
                    }

                    if (!PrIdAndSymptomSeverityViolationCountDict.ContainsKey(record.PRId))
                    {
                        PrIdAndSymptomSeverityViolationCountDict.Add(record.PRId, 0);
                    }

                    if (record.DegreeValue != symptom.DegreeValue)
                        PrIdAndSymptomSeverityViolationCountDict[record.PRId]++;

                    if (PrIdAndSymptomSeverityViolationCountDict[record.PRId] > maximumSymptomSeverityViolationCount)
                        maximumSymptomSeverityViolationCount = PrIdAndSymptomSeverityViolationCountDict[record.PRId];
                }
            }

            // 没有任何匹配的，不要浪费时间了
            if (maximumFitSymptomCount == 0)
            {
                return null;
            }

            // 以匹配症状数目优先,可能其他病友的症状数目比当前用户的多
            List<int> returnBestFitPrIds = new List<int>();

            if (symptomsCount == maximumFitSymptomCount)
            {
                // 当前用户拥有的症状，有其他病友完全匹配之，找到症状数和当前病人完全一致的病友
                List<int> bestFitPatientsPrIds = new List<int>();
                foreach (KeyValuePair<int, int> pair in PrIdAndFitSymptomsCountDict)
                {
                    if (pair.Value == maximumFitSymptomCount)
                    {
                        if (PrIdAndSymptomsCount[pair.Key] == maximumFitSymptomCount)
                            bestFitPatientsPrIds.Add(pair.Key);
                    }
                }

                if (bestFitPatientsPrIds.Count > 0)
                {
                    // 找到了这样的病友，再比较症状
                    returnBestFitPrIds = GetBestFitPatientRecordIdsBySymptomSeverity(bestFitPatientsPrIds,
                        PrIdAndSymptomSeverityViolationCountDict);
                }
                else
                {
                    // bestFitPatientsPrIds为空，填充之
                    // 填充所有其他病友，这些病友拥有当前用户的所有症状，而且还有自己独特的症状
                    foreach (KeyValuePair<int, int> pair in PrIdAndFitSymptomsCountDict)
                    {
                        if (pair.Value == maximumFitSymptomCount)
                            bestFitPatientsPrIds.Add(pair.Key);
                    }

                    // 其他病友的症状不仅包含了当前用户的所有症状，而且还有其他的症状,
                    // 此时找症状数最接近当前病友症状的用户
                    returnBestFitPrIds = GetBestFitPatientRecordIdsBySymptomsCount(bestFitPatientsPrIds, PrIdAndSymptomsCount,
                        PrIdAndSymptomSeverityViolationCountDict);
                }
            } // 如果当前用户的所有症状都可以被其他用户匹配
            else if (symptomsCount > maximumFitSymptomCount)
            {
                // 如果当前用户的所有症状不能完全被其他用户匹配,
                // 找到匹配症状的一个最大子集
                List<int> bestFitPatientsPrIds = new List<int>();
                foreach (KeyValuePair<int, int> pair in PrIdAndFitSymptomsCountDict)
                {
                    if (pair.Value == maximumFitSymptomCount)
                    {
                        bestFitPatientsPrIds.Add(pair.Key);
                    }
                }

                // bestFitPatientsPrIds现在包含了所以其他的病友，这些病友拥有最多和当前用户匹配的症状，
                // 但是这些病友的匹配症状不全
                returnBestFitPrIds = GetBestFitPatientRecordIdsBySymptomSeverity(bestFitPatientsPrIds, PrIdAndSymptomSeverityViolationCountDict);
            }
            else
            {
                // 不可能发生
                return null;
            }

            if (returnBestFitPrIds.Count == 0)
            {
                // 好像不可能发生
                return null;
            }


            List<UserInfo> returnBestFitPatientsList = new List<UserInfo>();

            for (int index = 0; index < returnBestFitPrIds.Count; index++)
            {
                int localPrId = returnBestFitPrIds[index];
                PatientRecordInfo prInfo = PatientBLL.Instance.GetPatientRecordInfoById(localPrId);
                UserInfo userInfo = UserBLL.Instance.GetUserInfo(prInfo.PatientId);
                returnBestFitPatientsList.Add(userInfo);
            }

            return returnBestFitPatientsList;
            #endregion
        }

        #endregion

        #region 病人Suvery记录
        public bool CheckPatientSurvey(int prId, int surveyType, DateTime surveyDate)
        {
            return DataAccess.PatientDAL.CheckPatientSurvey(prId, surveyType, surveyDate);

        }
        #endregion
    }
}
